﻿using AiBLSmartEdu.Module.CreditAnalysis.API.Services;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using Domain;
using FrameworkCore.Events;
using FrameworkCore.Helpers;
using FrameworkCore.Interfaces;
using Microsoft.Extensions.Logging;
using System.Globalization;
using System.Text.RegularExpressions;

namespace AiBLSmartEdu.Module.CreditAnalysis.API.HandleEvents;

public partial class EventConsumer :
    IConsumer<Event<CreditAnalysisEvents>>
{
    private readonly ILogger<EventConsumer> _logger;
    private readonly IOcrService _ocrService;
    private readonly PdfHelper _pdfHelper;
    private readonly DocumentServices _documentServices;

    public EventConsumer(
        ILogger<EventConsumer> logger,
        IOcrService ocrService,
        PdfHelper pdfHelper,
        DocumentServices documentServices)
    {
        _logger = logger;
        _ocrService = ocrService;
        _pdfHelper = pdfHelper;
        _documentServices = documentServices;
    }

    public async Task HandleEventAsync(Event<CreditAnalysisEvents> eventMessage)
    {
        try
        {
            await _documentServices.UpdatStatusAsync(eventMessage.Entity.Id, JobStatus.Pending);

            var text = string.Empty;
            var filePath = eventMessage.Entity.FilePath;

            _logger.LogInformation("开始解析");

            await _documentServices.UpdatStatusAsync(eventMessage.Entity.Id, JobStatus.Doing);

            if (filePath.EndsWith(".png"))
            {
                text = await _ocrService.PerformOcrAsync(filePath);
            }
            else if (filePath.EndsWith(".pdf"))
            {
                string outputDirectory = Path.GetDirectoryName(filePath)!;
                var psfs = _pdfHelper.SplitPdfIntoSinglePages(filePath, outputDirectory);

                foreach (var page in psfs)
                {
                    _pdfHelper.ConvertPdfToDocxFormat(Path.Combine(outputDirectory, page), outputDirectory, page.Replace("pdf", "docx"));
                }

                string[] docxFiles = Directory.GetFiles(outputDirectory, "*.docx");

                foreach (var docxFile in docxFiles)
                {
                    text += ExtractTextFromDocx(docxFile);
                }
            }

            _logger.LogInformation($"解析内容：{text}");

            await ExtractAndSumCreditInfoAsnyc(eventMessage.Entity.Id, text);
            //await ExtractAndSumLoanInfoAsnyc(eventMessage.Entity.Id, text);

            await _documentServices.UpdatStatusAsync(eventMessage.Entity.Id, JobStatus.Completed);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "处理事件时发生错误");
            // 根据需要，可能需要将状态更新为失败
            await _documentServices.UpdatStatusAsync(eventMessage.Entity.Id, JobStatus.Queueing);
        }
    }

    private static string ExtractTextFromDocx(string filePath)
    {
        var text = string.Empty;
        using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(filePath, false))
        {
            Body body = wordDoc.MainDocumentPart!.Document.Body!;
            foreach (var para in body.Elements<Paragraph>())
            {
                text += para.InnerText;
            }

            return text.Replace(" ", "");
        }
    }

    /// <summary>
    /// 提取和汇总信用卡信息
    /// </summary>
    /// <param name="id"></param>
    /// <param name="text">文本</param>
    private async Task ExtractAndSumCreditInfoAsnyc(long id,string text)
    {
        // 定义正则表达式模式
        // string pattern = @"信用额度([0-9,]+)，已使用额度([0-9,]+)";
        string pattern = @"([\u4e00-\u9fa5]+银行股份有限公司[\u4e00-\u9fa5]*)(?:.*?信用额度([0-9,]+)，已使用额度([0-9,]+))";

        // 创建正则表达式对象
        Regex regex = new Regex(pattern, RegexOptions.Singleline);

        // 查找匹配的内容
        MatchCollection matches = regex.Matches(text);

        string summary = string.Empty;
        decimal totalCreditLimit = 0;
        decimal totalUsedAmount = 0;


        // 遍历所有匹配项并处理
        foreach (Match match in matches)
        {
            // 提取信用额度和已使用额度
            string bankName = match.Groups[1].Value.Replace("日", "");
            string creditLimitStr = match.Groups[2].Value;
            string usedAmountStr = match.Groups[3].Value;

            // 去除千位分隔符并转换为数字
            decimal creditLimit = decimal.Parse(creditLimitStr, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
            decimal usedAmount = decimal.Parse(usedAmountStr, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);

            summary += @$"

银  行  名 称：{bankName}
信  用  额 度：{creditLimit}
已 使用 额 度：{usedAmountStr}
";

            // 累加
            totalCreditLimit += creditLimit;
            totalUsedAmount += usedAmount;
        }

        summary += @$"

            总计
信  用  额 度：{totalCreditLimit}
已 使用 额 度：{totalUsedAmount}
";
        await _documentServices.UpdatContentSummaryAsync(id, text, summary);
    }

    /// <summary>
    /// 提取和汇总贷款信息
    /// </summary>
    ///  <param name="id"></param>
    /// <param name="text">文本</param>
    /// <returns></returns>
    private async Task ExtractAndSumLoanInfoAsnyc(long id, string text)
    {
        // 定义正则表达式模式
        string pattern = @"(\d{4}年\d{2}月\d{2}日)([\s\S]*?)(?:发放的|授信，额度有效期)([\d,]+)元\(人民币\)(?:[\s\S]*?)(?:(?:余额|余额为)([\d,\.]+)|(?:信用额度)([\d,\.]+)[\s\S]*?余额为([\d,\.]+))|(\d{4}年\d{2}月\d{2}日)([\s\S]*?)(?:发放的|授信，额度有效期)([\d,]+)元\(人民币\)([\s\S]*?)(?:余额|余额为)([\d,\.]+)|(\d{4}年\d{2}月\d{2}日)([\s\S]*?)(?:发放的|授信，额度有效期)([\d,]+)元\(人民币\)([\s\S]*?)(?:信用额度)([\d,\.]+)[\s\S]*?余额为([\d,\.]+)";

        // 创建正则表达式对象
        Regex regex = new Regex(pattern, RegexOptions.Singleline);

        // 查找匹配的内容
        MatchCollection matches = regex.Matches(text);

        string summary = string.Empty;
        decimal totalCreditLimit = 0;
        decimal totalUsedAmount = 0;

        // 遍历所有匹配项并处理
        foreach (Match match in matches)
        {
            // 提取信用额度和已使用额度
            string bankName = match.Groups[1].Value.Replace("日", "");
            string creditLimitStr = match.Groups[2].Value;
            string usedAmountStr = match.Groups[3].Value;

            // 去除千位分隔符并转换为数字
            decimal creditLimit = decimal.Parse(creditLimitStr, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
            decimal usedAmount = decimal.Parse(usedAmountStr, NumberStyles.AllowThousands, CultureInfo.InvariantCulture);

            summary += @$"

银  行  名 称：{bankName}
信  用  额 度：{creditLimit}
已 使用 额 度：{usedAmountStr}

";

            // 累加
            totalCreditLimit += creditLimit;
            totalUsedAmount += usedAmount;
        }

        summary += @$"

            总计
信  用  额 度：{totalCreditLimit}
已 使用 额 度：{totalUsedAmount}

";
        await _documentServices.UpdatContentSummaryAsync(id, text, summary);
    }
}